package com.xxxx.server.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xxxx.server.AdminUtils;
import com.xxxx.server.mapper.AdminMapper;
import com.xxxx.server.mapper.AdminRoleMapper;
import com.xxxx.server.pojo.Admin;
import com.xxxx.server.pojo.AdminRole;
import com.xxxx.server.pojo.RespBean;
import com.xxxx.server.service.IAdminService;
import com.xxxx.server.utils.AssertUtil;
import com.xxxx.server.utils.JwtUtils;
import com.xxxx.server.utils.PhoneUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.security.Principal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author zhoubin
 * @since 2020-10-15
 */
@Service
public class AdminServiceImpl extends ServiceImpl<AdminMapper, Admin> implements IAdminService {

	@Autowired
	private UserDetailsService userDetailsService;
	@Autowired
	private PasswordEncoder passwordEncoder;
	@Autowired
	private JwtUtils jwtUtils;
	@Value("${jwt.tokenHead}")
	private String tokenHead;
	@Autowired
	private AdminMapper adminMapper;
	@Autowired
	private AdminRoleMapper adminRoleMapper;
	@Autowired
	private IAdminService adminService;

	public static void main(String[] args) {
		PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
		String encode = passwordEncoder.encode("admin");
		boolean admin = passwordEncoder.matches("admin", "$2a$10$IikwpHOEst4OzclJYnMDou7pvrJG1hdxo5IUTc0woD7I/UgfYuWeS");
		System.out.println(admin);
		System.out.println(encode);
	}

	/**
	 * 登录返回token
	 *
	 * @param username
	 * @param password
	 * @param code
	 * @param request
	 * @return
	 */
	@Override
	public RespBean login(String username, String password, String code, HttpServletRequest request) {
		String captcha = (String) request.getSession().getAttribute("captcha");
		if (StringUtils.isBlank(code) || !captcha.equals(code)) {
			return RespBean.error("验证码填写错误！");
		}
		UserDetails userDetails = userDetailsService.loadUserByUsername(username);
		if (null == userDetails || !passwordEncoder.matches(password, userDetails.getPassword())) {
			return RespBean.error("用户名或密码不正确!");
		}
		if (!userDetails.isEnabled()){
			return RespBean.error("账号被禁用，请联系管理员!");
		}
		UsernamePasswordAuthenticationToken authentication =
				new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
		SecurityContextHolder.getContext().setAuthentication(authentication);

		String token = jwtUtils.generatorToken(userDetails);
		Map<String, String> tokenMap = new HashMap<>();
		tokenMap.put("token", token);
		tokenMap.put("tokenHead", tokenHead);
		return RespBean.success("登录成功", tokenMap);
	}

	/**
	 * 根据用户名获取用户信息
	 * @param username
	 * @return
	 */
	@Override
	public Admin getUserByUsername(String username) {
		return adminMapper.selectOne(new QueryWrapper<Admin>().eq("username",username));
	}

	/**
	 * 修改用户信息
	 * @param admin
	 */
	@Override
	public void updateAdminInfo(Admin admin) {

		AssertUtil.isTrue(null == admin || null == admin.getId(),"用户不存在!");
		AssertUtil.isTrue(null == adminMapper.selectOne(
				new QueryWrapper<Admin>().eq("id",admin.getId())),"用户不存在!");

		AssertUtil.isTrue(admin.getName().trim().length() == 0 ,"用户昵称不能为空！");
		admin.setName(admin.getName().trim());
		AssertUtil.isTrue(admin.getAddress().trim().length() == 0,"用户地址不能为空！");
		admin.setAddress(admin.getAddress().trim());
		// 校验手机号格式
		AssertUtil.isTrue(!PhoneUtil.isMobile(admin.getPhone()),"手机号格式不合法！");


		// 更新
		int row = adminMapper.updateAdminInfo(admin);

		AssertUtil.isTrue(row < 0,"用户信息更新失败！");
	}

	/**
	 * 修改用户密码
	 * @param ruleForm
	 */
	@Override
	public void updatePassword(Map<String, Object> ruleForm) {
		// 参数不能为空
		AssertUtil.isTrue(null == ruleForm ,"参数异常！");

		// 获取用户输入数据
		Integer adminId = (Integer) ruleForm.get("adminId");
		// 获取密码
		String oldPass = (String) ruleForm.get("oldPass");
		String pass = (String) ruleForm.get("pass");
		String checkPass = (String) ruleForm.get("checkPass");
		// 参数校验
		checkParamForPassword(adminId, oldPass, pass, checkPass);
		// 修改密码
		AssertUtil.isTrue(adminMapper.updatePasswordById(adminId,passwordEncoder.encode(pass)) != 1,
				"密码修改失败!");

	}

	/**
	 * 头像显示
	 * @param principal
	 * @param file
	 * @return
	 */
	@Override
	public Integer updateFace(Principal principal, MultipartFile file)  throws IOException {
		//1.根据用户名查询用户
		Admin admin = adminService.getAdminByUserName(principal.getName());

		System.out.println(admin.toString());
		System.out.println("=================");
		System.out.println("上传前数据库内的路径");
		//System.out.println(adminMapper.selectById(admin.getId()).getUserFace());

		//2.将图片上传到七牛云存储，获取请求路径
		System.out.println("上传中");
		//String imgUrl = new QiniuUploadUtil().upload(admin.getUsername() + System.currentTimeMillis(), file.getBytes());

		//String imgUrl = new QiniuUploadUtil().upload(admin.getUsername(), file.getBytes());

		//3.把得到的路径存储到数据库中
		//admin.setUserFace(imgUrl);
		//int i = adminMapper.updateById(admin);

		System.out.println("图片路径");
		//System.out.println(imgUrl);

		//int i = adminMapper.updateFaceById(imgUrl, admin.getId());

//		System.out.println("修改后数据库内的路径");
//		System.out.println(adminMapper.selectById(admin.getId()).getUserFace());
		return 1;
	}

	@Override
	public int updateUserface(String url, Integer id) {
		return adminMapper.updateUserface(url, id);
	}

	/**
	 * 根据用户名获取用户
	 */
	@Override
	public Admin getAdminByUserName(String username) {
		return adminMapper.selectOne(new QueryWrapper<Admin>().eq("username", username));
	}

	@Override
	public void updatetu(String url, HttpServletRequest request) {
		String str="http://"+url;//将地址拼接完整
		Map<String, String> map=new HashMap<>();//存入集合
		map.put("userFace",str);
		map.put("id",request.getParameter("id"));
		adminMapper.updatetuDao(map);
	}

	/**
	 * 校验修改密码参数
	 * @param adminId
	 * @param oldPass
	 * @param pass
	 * @param checkPass
	 */
	private void checkParamForPassword(Integer adminId, String oldPass, String pass, String checkPass) {
		AssertUtil.isTrue(null == adminId,"无法获取用户信息");
		AssertUtil.isTrue(StringUtils.isBlank(oldPass),"原密码不能为空");
		AssertUtil.isTrue(StringUtils.isBlank(pass), "新密码不能为空！");
		AssertUtil.isTrue(StringUtils.isBlank(checkPass), "确认密码不能为空！");
		AssertUtil.isTrue(!pass.equals(checkPass), "确认密码不一致！");
		AssertUtil.isTrue(oldPass.equals(pass), "新密码不能为原密码相同！");

		// 查询用户
		Admin admin = adminMapper.selectOne(new QueryWrapper<Admin>().eq("id", adminId));
		AssertUtil.isTrue(null == admin, "用户不存在！");
		AssertUtil.isTrue(!passwordEncoder.matches(oldPass,admin.getPassword()),"旧密码不正确！");
	}

	/**
	 * 获取所有操作员
	 * @param keywords
	 * @return
	 */
    @Override
    public List<Admin> getAllAdmins(String keywords) {
        return adminMapper.getAllAdmins(AdminUtils.getCurrentAdmin().getId(),keywords);
    }


	/**
	 * 更新操作员角色
	 * @param adminId
	 * @param rids
	 * @return
	 */
	@Override
	@Transactional
	public RespBean updateAdminRole(Integer adminId, Integer[] rids) {

		adminRoleMapper.delete(new QueryWrapper<AdminRole>().eq("adminId",adminId));
		Integer result = adminRoleMapper.addAdminRole(adminId,rids);
		if (rids.length==result){
			return RespBean.success("角色更新成功");
		}
		return RespBean.error("角色更新失败");
	}
}
